﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Biciq.Datos;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.DomainServices.Client;

namespace Biciq.Silverlight.UI
{
    public class EditarAccesoVistaModelo:VistaModeloBase
    {
        #region campos
        private Rol _rolActual;
        private bool _modoEditar;
        private RelayCommand _comandoGuardar;
        private RelayCommand _comandoCancelar;
        private RelayCommand _nodoSeleccion;
        private Arbol _nodoSeleccionado;
        private ObservableCollection<Arbol> _listaArbol;
        #endregion

        #region comandos

        /// <summary>
        /// Comando para guardar
        /// </summary>
        public RelayCommand ComandoGuardar
        {
            get
            {

                if (_comandoGuardar == null)
                {
                    _comandoGuardar = new RelayCommand
                    (
                        p => GuardarRol()
                    );
                }
                return _comandoGuardar;
            }

        }

        /// <summary>
        /// Comando para cancelar 
        /// </summary>
        public RelayCommand ComandoCancelar
        {
            get
            {
                if (_comandoCancelar == null)
                {
                    _comandoCancelar = new RelayCommand
                    (
                        p => CerrarVentana()
                    );
                }
                return _comandoCancelar;
            }

        }

        #endregion

        #region eventos
        public EventHandler EventoCerrarEditor;
        #endregion

        #region propiedades
        /// <summary>
        /// camando para captar un nodo IsChecked
        /// </summary>
        public RelayCommand NodoSeleccion
        {
            get
            {
                return _nodoSeleccion ?? (_nodoSeleccion = new RelayCommand(SeleccionaNodoPadreEHijo));
            }
        }

        /// <summary>
        /// Nodo Seleccionado del árbol 
        /// </summary>
        public Arbol NodoSeleccionado
        {
            get
            {
                return _nodoSeleccionado;
            }
            set
            {
                if (_nodoSeleccionado != value)
                {
                    _nodoSeleccionado = value;
                    RaisePropertyChanged("NodoSeleccionado");
                }

            }
        }

        /// <summary>
        /// Lista de árboles
        /// </summary>
        public ObservableCollection<Arbol> ListaArbol
        {
            get
            {
                return _listaArbol;
            }
            set
            {
                if (_listaArbol != value)
                {
                    _listaArbol = value;
                    RaisePropertyChanged("ListaArbol");
                }
            }
        }


        /// <summary>
        /// Rol actual para editar o crear uno nuevo
        /// </summary>
        public Rol RolActual
        {
            get { return _rolActual; }
            set
            {
                _rolActual = value;
                _rolActual.PropertyChanged += (ob, ev) =>
                {
                    //Indica si hubo cambios en el RolActual
                    IsDirty = true;
                    RaisePropertyChanged("RolActual." + ev.PropertyName);
                };
                RaisePropertyChanged("RolActual");
            }
        }

        /// <summary>
        /// Propiedad que nos indica si un rol se va a editar
        /// </summary>
        public bool ModoEditar
        {
            get { return _modoEditar; }
            set
            {
                _modoEditar = value;
            }
        }


        #endregion

        #region constructores
        public EditarAccesoVistaModelo(Rol rol)
        {
            RolActual = rol;

            obtenerRecursos(rol);
            _modoEditar = true;
        }


        #endregion

        #region metodos privados

        /// <summary>
        /// para saber que nodo esta Seleccionado
        /// </summary>
        /// <param name="parameter">parametro del comando</param>
        private void SeleccionaNodoPadreEHijo(object Nodo)
        {
            Arbol arbol = (Arbol)Nodo;
            if (arbol.ArbolHijo != null)
            {

                foreach (var item in arbol.ArbolHijo)
                {
                    item.Seleccionado = (bool)arbol.Seleccionado;

                    if (item.ArbolHijo != null)
                    {
                        foreach (var i in item.ArbolHijo)
                        {
                            i.Seleccionado = (bool)item.Seleccionado;

                            if (i.ArbolHijo != null)
                            {
                                foreach (var x in i.ArbolHijo)
                                {
                                    x.Seleccionado = (bool)i.Seleccionado;
                                }
                            }

                        }
                    }
                }
            }

            seleccionarPadre(arbol);
        }

        private Arbol seleccionarPadre(Arbol arbol)
        {

            if (arbol.IdPadres != null)
            {

                foreach (var item in arbol.IdPadres)
                {
                    if (!arbol.Seleccionado && arbol.IdPadres != null)
                    {
                        foreach (var arbolPadre in arbol.IdPadres)
                        {
                            if (arbolPadre.Id == arbol.IdPadre)
                            {

                                foreach (var padre in arbolPadre.ArbolHijo)
                                {
                                    if (arbolPadre.Id == arbol.IdPadre)
                                    {
                                        if (padre.Seleccionado)
                                        {
                                            return arbol;
                                        }
                                    }

                                }
                            }

                        }
                    }

                    item.Seleccionado = arbol.Seleccionado;
                    if (item.IdPadres != null)
                    {
                        seleccionarPadre(item);
                    }
                }
            }

            return arbol;
        }

        /// <summary>
        /// Método en el cual se obtienen los accesos
        /// </summary>
        private void obtenerRecursos(Rol rol)
        {
            var listTempRecurso = new List<Recurso>();
            var listaRecurso = new List<Recurso>();
            this._listaArbol = new ObservableCollection<Arbol>();

            BiciqContexto.Recursos.Clear();
            BiciqContexto.Rols.Clear();

            BiciqContexto.Load(BiciqContexto.GetRecursoesQuery()).Completed += delegate
            {
                listaRecurso = BiciqContexto.Recursos.ToList();

                var datos = BiciqContexto.Recursos;
                BiciqContexto.Recursos.Clear();
                BiciqContexto.Load(BiciqContexto.GetRolRecursoIdQuery(rol.id)).Completed += delegate
                {

                    var arbol = new Arbol();
                    arbol.Descripcion = rol.nombre;
                    arbol.Seleccionado = false;
                    arbol.ArbolHijo = new ObservableCollection<Arbol>();

                    listTempRecurso = datos.ToList();
                    if (listaRecurso != null)
                    {
                        foreach (var item in listaRecurso)
                        {
                            var a = new Arbol();
                            a.Descripcion = item.descripcion;
                            a.Id = item.id;
                            if (a.IdPadres == null)
                                a.IdPadres = new List<Arbol>();

                            if (listTempRecurso.Where(e => e.id.ToString().Trim().Equals(item.id.ToString().Trim())).ToList().Count > 0)
                            {
                                a.Seleccionado = true;
                            }

                            if (item.idPadre == "0")
                            {
                                _listaArbol.Add(generaArbol(a, item.id, listaRecurso, listTempRecurso));
                            }

                        }
                    }

                };

            };
        }

        /// <summary>
        /// Método en el cual se genera el árbol
        /// </summary>
        private Arbol generaArbol(Arbol arbolHijo, string id, List<Recurso> listaRecurso, List<Recurso> listTempRecurso)
        {

            if (arbolHijo.ArbolHijo == null)
                arbolHijo.ArbolHijo = new ObservableCollection<Arbol>();

            foreach (var item in listaRecurso.Where(r => r.idPadre == id).ToList())
            {
                var hijo = new Arbol();
                hijo.Descripcion = item.descripcion;
                hijo.Id = item.id;
                hijo.IdPadre = arbolHijo.Id;
                if (hijo.IdPadres == null)
                {
                    hijo.IdPadres = new List<Arbol>();
                }
                hijo.IdPadres.Add(arbolHijo);

                foreach (var r in listTempRecurso)
                {
                    if (r.id == item.id)
                    {
                        hijo.Seleccionado = true;
                    }
                }

                var tempR = listaRecurso.Where(r => r.idPadre == item.id).ToList();

                if (tempR.Count > 0)
                {
                    generaArbol(hijo, item.id, listaRecurso, listTempRecurso);
                }
                arbolHijo.ArbolHijo.Add(hijo);
            }

            return arbolHijo;
        }



        /// <summary>
        /// Método en el cual se guarda el ROl
        /// </summary>
        private void GuardarRol()
        {

            bool validaAcceso = true;

            List<string> listaNueva = new List<string>();

            foreach (var item in ListaArbol)
            {
                if (item.Seleccionado)
                {

                    listaNueva.Add(item.Id);
                }

                foreach (var i in item.ArbolHijo)
                {
                    if (i.Seleccionado)
                    {
                        validaAcceso = false;
                        listaNueva.Add(i.Id);
                    }
                    if (i.ArbolHijo != null)
                    {
                        foreach (var r in i.ArbolHijo)
                        {
                            if (r.Seleccionado)
                            {
                                validaAcceso = false;
                                listaNueva.Add(r.Id);
                            }

                            if (r.ArbolHijo != null)
                            {
                                foreach (var m in r.ArbolHijo)
                                {
                                    if (m.Seleccionado)
                                    {
                                        validaAcceso = false;
                                        listaNueva.Add(m.Id);
                                    }
                                }
                            }
                        }
                    }

                }

            }



            //if (validaAcceso)//Se valida si escogió por lo menos una acceso
            //{
            //    LogicStudio.Framework.UI.Controles.CuadroDialogo.Mostrar(string.Format(RecursosLenguaje.Recursos.ValidaAccesoSeleccionado, RecursosLenguaje.Recursos.Acceso), RecursosLenguaje.Recursos.Acceso, LogicStudio.Framework.UI.Utilidades.TipoVentana.Ok);
            //}
            //else
            //{


            BiciqContexto.AgregarRolRecurso(listaNueva, RolActual.id).Completed += (o, v) =>
            {
                InvokeOperation<Result> result = (InvokeOperation<Result>)o;
                if (!result.Value.estado)
                {
                    IsDirty = false;
                    MessageBox.Show(result.Value.mensaje);
                }
                else
                {
                    IsDirty = true;
                    LogicStudio.Framework.UI.Controles.CuadroDialogo.Mostrar(RecursosLenguaje.Recursos.AccesoARolGrabadoExitoso, RecursosLenguaje.Recursos.Acceso, LogicStudio.Framework.UI.Utilidades.TipoVentana.Ok);

                    CerrarVentana();
                }
            };
            //}

        }

        private void CerrarVentana()
        {
            //pregunto si alguien se suscribio al evento
            if (EventoCerrarEditor != null)
            {
                EventoCerrarEditor(null, null);

            }
        }

        #endregion

        #region metodos publicos

        #endregion
    }
}
